/*
 * @Description: 数据字典
 * @Author: DSY
 * @Date: 2022-03-19 22:53:48
 * @LastEditors: DHL
 * @LastEditTime: 2022-08-31 17:19:48
 */

import { defineComponent, computed, onMounted, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { assign, cloneDeep, result } from 'lodash-es'
import { TwTableOptions } from '/@/types/table.d'
import {
  arrayRemoveItem,
  arraySerializeToStr,
  getTreeParentName,
  listToTree
} from '/@/utils/twUtils'

import {
  DataDicModel,
  DataDicPageParams,
  DataDicPageResultModel
} from '/@/api/system/model/dataDicModel'

import {
  apiDataDicBatchDeleteByIds,
  apiDataDicListDataType,
  apiDataDicSearch,
  apiDataDicUpdateById,
  apiDataDicUpdateParentIdByTypeCode
} from '/@/api/system/dataDic'

import type Node from 'element-plus/es/components/tree/src/model/node'
import type { DragEvents } from 'element-plus/es/components/tree/src/model/useDragNode'
import { stringUtils } from '/@/utils/stringUtils'

import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import dataDicForm from './form.vue'
import dataDicTypeForm from './dataDicTypeForm.vue'

export default defineComponent({
  name: 'DataDic',
  components: { Splitpanes, Pane, dataDicForm, dataDicTypeForm },
  setup(props) {
    //////////////////////////////////////////////////
    // 属性
    //////////////////////////////////////////////////

    const loading = ref(false)
    const loadingByDel = ref(false)

    const treeData = ref([] as Array<DataDicModel>)

    let selectTreeNode = { id: '', parentId: '', typeCode: '', typeName: '', type: '' }
    let treeProps = ref({
      label: 'typeName',
      children: 'children'
    })

    /**
     * 表格数据
     */
    const tableData = ref()

    /**
     * 查询表单
     */
    const searchFormRef = ref()

    /**
     * 数据列表
     */
    const tableRef = ref()

    /**
     * 表单
     */
    const formRef = ref()

    /**
     * 是否有选中的行
     */
    const isSelectRows = computed(() => {
      let selectRows: Array<DataDicModel> = []
      if (tableRef.value) {
        selectRows = tableRef.value.getSelectRows()
      }
      return selectRows.length < 1
    })

    //////////////////////////////////////////////////
    // 查询表单
    //////////////////////////////////////////////////

    const defaultSearchForm = {
      id: '', // 编号
      typeCode: '', // 类别编码
      typeName: '', // 类别名称
      dataValue: '', // 字典值
      dataName: '', // 字典值名称
      type: '', // 字典类型（0，分类；1，字典）
      zxbs: '', // 注销标示 （0，未注销；1，注销）
      dataNameEn: '', // 字典英文名称
      seqNum: 0, // 顺序号
      smartCode: '', // 助记码
      tag1: '', // 扩展1
      tag2: '', // 扩展2
      tag3: '', // 扩展3
      parentId: '', // 父ID
      remark: '', // 描述
      queryLikeStr: ''
    }

    /**
     * 查询表单
     */
    const searchForm = reactive(cloneDeep(defaultSearchForm))

    //////////////////////////////////////////////////
    // 表格
    //////////////////////////////////////////////////

    /**
     * 表格配置
     */
    const tableOptions = reactive<TwTableOptions>({
      id: 'dataDicTable',
      sortConfig: {
        defaultSort: [{ field: 'seqNum', order: 'asc' }]
      },
      columns: [
        { type: 'checkbox', fixed: 'left', title: '复选', width: 40 },
        { type: 'seq', fixed: 'left', title: '序号', width: 50 },
        { field: 'typeCode', title: '类别编码', sortable: true },
        { field: 'typeName', title: '类别名称', sortable: true },
        { field: 'dataValue', title: '字典值', sortable: true },
        { field: 'dataName', title: '字典值名称', sortable: true },
        { field: 'dataNameEn', title: '字典英文名称', sortable: true },
        { field: 'seqNum', title: '顺序号', sortable: true, slots: { default: 'dataDicSeq' } },
        { field: 'cssName', title: '回显样式', sortable: false, params: { dict: 'CSS_NAME' } },
        {
          field: 'zxbs',
          title: '注销标示',
          sortable: true,
          params: { dict: 'ZXBS' }
        },
        { field: 'remark', title: '描述', sortable: true },
        { title: '操作', fixed: 'right', width: 110, slots: { default: 'action' } }
      ]
    })

    /**
     * 绑定事件
     */
    const tableEvents = reactive({})

    //////////////////////////////////////////////////
    // 函数
    //////////////////////////////////////////////////

    /**
     * 查询表格数据函数
     * @param queryParams
     */
    function searchList(queryParams: DataDicPageParams) {
      loading.value = true

      let t_params = assign(queryParams, searchForm, {
        type: '1'
      })

      if (selectTreeNode) {
        if (selectTreeNode.type === '1') {
          assign(t_params, {
            typeCode: selectTreeNode.typeCode
          })
        } else {
          assign(t_params, {
            parentId: selectTreeNode.typeCode
          })
        }
      }

      apiDataDicSearch(t_params)
        .then((result: DataDicPageResultModel) => {
          tableData.value = result
        })
        .catch(() => { })
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 查询表格数据
     */
    function handleSearch() {
      tableRef.value.handleQuery()
    }

    /**
     * 刷新
     */
    function handleRefresh() {
      tableRef.value.handleReload()
    }

    /**
     * 重置
     */
    function handleReset() {
      assign(searchForm, cloneDeep(defaultSearchForm))
      tableRef.value.handleQuery()
    }

    /**
     * 刷新主页数据
     */
    function handleRefreshIndex() {
      handleRefresh()
      handleSearchDictType()
    }

    /**
     * 批量删除
     */
    function handleDelete(row?: DataDicModel) {
      let selectRows: Array<DataDicModel> = []

      if (row) {
        selectRows = [row]
      } else {
        selectRows = tableRef.value.getSelectRows()
      }

      ElMessageBox.confirm(`此操作将删除${selectRows.length}条记录, 是否继续?`, '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          loadingByDel.value = true
          const ids = arraySerializeToStr(selectRows, 'id')
          apiDataDicBatchDeleteByIds(ids)
            .then((result) => {
              if (result?.success) {
                handleRefresh()
                handleSearchDictType()
                ElMessage.success(result.message)
              } else {
                ElMessage.error(result?.message)
              }
            })
            .catch(() => { })
            .finally(() => {
              loadingByDel.value = false
            })
        })
        .catch(() => {
          ElMessage.info('删除被取消了')
        })
    }

    /**
     * 弹出表单
     */
    function handleOpenForm(action: string, row?: DataDicModel) {
      if (stringUtils.isEmpty(selectTreeNode.typeCode)) {
        ElMessage.warning('请选择字典类别')
        return
      }

      const parentName = getTreeParentName(
        dataDicTypeList,
        'typeCode',
        'parentId',
        'typeName',
        selectTreeNode
      )

      let parentId = selectTreeNode.typeCode

      if (selectTreeNode.type === '1') {
        arrayRemoveItem(parentName, selectTreeNode.typeName)
        parentId = selectTreeNode.parentId
      }

      formRef.value.handleOpen(
        action,
        row,
        {
          parentId: parentId,
          parentName: parentName.join(' - ')
        },
        selectTreeNode
      )
    }

    /**
     * 根据主键更新
     * @param row
     */
    function handleUpdateById(row: DataDicModel) {
      loading.value = true
      apiDataDicUpdateById(row)
        .then((result) => {
          if (result?.success) {
            ElMessage.success(result.message)

            handleRefresh()
          } else {
            ElMessage.error(result?.message)
          }
        })
        .catch(() => { })
        .finally(() => {
          loading.value = false
        })
    }

    //////////////////////////////////////////////////
    // 字典分类
    //////////////////////////////////////////////////
    const dictTypeRef = ref()
    const treeKeyWord = ref()
    const dataDicTypeFormRef = ref()
    let dataDicTypeList: any = []

    /**
     * 查询字典类型
     */
    function handleSearchDictType() {
      apiDataDicListDataType(searchForm).then((result) => {
        if (result?.success) {
          dataDicTypeList = result.data
          treeData.value = listToTree(result.data, 'typeCode', 'parentId', '')
        }
      })
    }

    /**
     * 字典类型过滤
     */
    watch(treeKeyWord, (val: string) => {
      dictTypeRef.value!.filter(val)
    })

    /**
     * 字典类型过滤
     */
    function handleFilterDictType(value: string, data: any) {
      if (!value) return true
      return data.typeName.includes(value)
    }

    /**
     * tree展开折叠
     */
    function handleExpandTree(isExpand: boolean) {
      dictTypeRef.value.store._getAllNodes().forEach((item: { expanded: boolean }) => {
        item.expanded = isExpand
      })
    }

    /**
     * 节点点击
     */
    function handleNodeClick(treeNode: any) {
      selectTreeNode = treeNode
      handleSearch()
    }

    /**
     * 分类表单
     * @param treeNode
     */
    function hanldeOpenDictTypeForm(action: string, treeNode?: DataDicModel) {
      let parentName: any[] = []
      let parentId = ''
      if (action === 'add' && treeNode) {
        parentName = getTreeParentName(
          dataDicTypeList,
          'typeCode',
          'parentId',
          'typeName',
          treeNode
        )
        parentId = treeNode.typeCode
      } else if (action === 'edit') {
        const parentNodes = dataDicTypeList.filter((item: { typeCode: any }) => {
          return item.typeCode === treeNode?.parentId
        })

        const parentNode = parentNodes[0]

        parentId = parentNode?.typeCode

        parentName = getTreeParentName(
          dataDicTypeList,
          'typeCode',
          'parentId',
          'typeName',
          parentNode
        )
      }

      dataDicTypeFormRef.value.handleOpen(action, treeNode, {
        parentId: parentId,
        parentName: parentName.join(' - ')
      })
    }

    /**
     * 分类删除
     * @param treeNode
     */
    function hanldeDelDictType(treeNode: any) {
      if (treeNode && treeNode.children && treeNode.children.length > 0) {
        ElMessage.warning('请先删除子级节点')
        return
      }

      ElMessageBox.confirm(`此操作将删除1条记录, 是否继续?`, '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          apiDataDicBatchDeleteByIds(treeNode.dicId)
            .then((result) => {
              if (result?.success) {
                handleSearchDictType()
                ElMessage.success(result.message)
              } else {
                ElMessage.error(result?.message)
              }
            })
            .catch(() => { })
            .finally(() => { })
        })
        .catch(() => {
          ElMessage.info('删除被取消了')
        })
    }

    /**
     * 字典类别拖拽
     */
    function handleDropDicType(
      draggingNode: Node,
      dropNode: Node,
      dropType: any,
      ev: DragEvents
    ) {
      let pid = ''
      if ('inner' === dropType) {
        pid = dropNode.data.typeCode
      } else {
        pid = dropNode.data.parentId
      }

      if (stringUtils.isEmpty(pid)) {
        return
      }

      let nodeData: DataDicModel = draggingNode.data as DataDicModel

      apiDataDicUpdateParentIdByTypeCode(nodeData.typeCode, pid).then((result) => {
        if (result?.success) {
          ElMessage.success(result.message)
        } else {
          ElMessage.error(result?.message)
        }
      })
    }

    //////////////////////////////////////////////////
    // 生命周期
    //////////////////////////////////////////////////
    onMounted(() => {
      handleSearchDictType()
    })

    return {
      loading,
      loadingByDel,
      tableData,
      searchFormRef,
      tableRef,
      formRef,
      searchForm,
      tableOptions,
      tableEvents,
      isSelectRows,
      treeData,
      treeProps,
      treeKeyWord,
      searchList,
      handleSearch,
      handleRefresh,
      handleReset,
      handleDelete,
      handleOpenForm,
      dictTypeRef,
      handleFilterDictType,
      handleSearchDictType,
      handleNodeClick,
      handleExpandTree,
      hanldeOpenDictTypeForm,
      hanldeDelDictType,
      dataDicTypeFormRef,
      handleDropDicType,
      handleRefreshIndex,
      handleUpdateById
    }
  }
})
